home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 22 / Cream of the Crop 22.iso / program / snip9611.zip / PARA_FAQ.TXT < prev    next >
Text File  |  1996-11-24  |  12KB  |  272 lines

  1. +++Date last modified: 02-Nov-1995
  2.  
  3.                    PC Parallel Port Mini-FAQ
  4.  
  5. By Kris Heidenstrom (kheidens@actrix.gen.nz), revision 3, 950331
  6.  
  7. 1. INTRO
  8.  
  9. This is a four printed page mini-FAQ with the information essential
  10. for programming the PC parallel port.  Many subjects are not covered
  11. in detail.  View on an 80-column screen with 8-column tab stops.
  12. Comments and suggestions to kheidenstrom@actrix.gen.nz.
  13.  
  14. A parallel port links software to the real world.  To software, the
  15. parallel port is three 8-bit registers occupying three consecutive
  16. addresses in the I/O space.  To hardware, the port is a female 25-pin
  17. D-sub connector, carrying twelve latched outputs from the computer,
  18. accepting five inputs into the computer, with eight ground lines.
  19.  
  20. The normal function of the port is to transfer data to a printer
  21. through the eight data pins, using the remaining signals as flow
  22. control and miscellaneous controls and indications.
  23.  
  24. The original port was implemented with TTL/LS logic.  Modern ports are
  25. implemented in an ASIC or a combined serial/parallel port chip, but
  26. are backward compatible.  Some modern ports are bidirectional.
  27.  
  28. 2. BIOS LPT PORT TABLE
  29.  
  30. A parallel port is identified by its I/O base address, and also by its
  31. LPT port number.  The BIOS power-on self-test checks specific I/O
  32. addresses for the presence of a parallel port, and builds a table of
  33. I/O addresses in the low memory BIOS data area, starting at address
  34. 0040:0008 (or 0000:0408).
  35.  
  36. This table contains up to three 16-bit words.  Each entry is the I/O
  37. base address of a parallel port.  The first word is the I/O base
  38. address of LPT1, the second is LPT2, etc.  If less than three ports
  39. were found, the remaining entries in the table are zero.  DOS, and
  40. the BIOS printer functions (accessed via int 17h), use this table to
  41. translate an LPT port number to a physical port at a certain address.
  42.  
  43. The addresses are checked in a specific order, and addresses are put
  44. into the table as they are found, so the table will never have gaps.
  45. A particular I/O address does not necessarily always equate to the
  46. same specific LPT port number, although there are conventions.
  47.  
  48. 2.1  ADDRESSING CONVENTIONS
  49.  
  50. The video card's parallel port is normally at 3BCh.  This address is
  51. checked first by the BIOS, so if a port exists there, it will be LPT1.
  52. The BIOS then checks at 378h, then at 278h.  AFAIK there is no
  53. standard address for a fourth port, and BIOSes only look for three.
  54.  
  55. 3. DIRECT HARDWARE ACCESS
  56.  
  57. The port consists of three 8-bit registers at adjacent addresses in
  58. the processor's I/O space.  The registers are defined relative to
  59. the I/O base address, and are at IOBase+0, IOBase+1, and IOBase+2
  60. (for example if IOBase is 3BCh, then the registers are at 3BCh,
  61. 3BDh, and 3BEh).  Always use 8-bit I/O accesses on these registers.
  62.  
  63. 3.1  DATA REGISTER
  64.  
  65. The data register is at IOBase+0.  It may be read and written (using
  66. the IN and OUT instructions, or inportb() and outportb() or inp()
  67. and outp()).  Writing a byte to this register causes the byte value
  68. to appear on pins 2 through 9 of the D-sub connector (unless the port
  69. is bidirectional and is set to input mode).  The value will remain
  70. latched and stable until you write another value to the data
  71. register.  Reading this register yields the state of those pins.
  72.  
  73.         7 6 5 4 3 2 1 0
  74.         * . . . . . . .  D7 (pin 9), 1=High, 0=Low
  75.         . * . . . . . .  D6 (pin 8), 1=High, 0=Low
  76.         . . * . . . . .  D5 (pin 7), 1=High, 0=Low
  77.         . . . * . . . .  D4 (pin 6), 1=High, 0=Low
  78.         . . . . * . . .  D3 (pin 5), 1=High, 0=Low
  79.         . . . . . * . .  D2 (pin 4), 1=High, 0=Low
  80.         . . . . . . * .  D1 (pin 3), 1=High, 0=Low
  81.         . . . . . . . *  D0 (pin 2), 1=High, 0=Low
  82.  
  83. 3.2  STATUS REGISTER
  84.  
  85. The status register is at IOBase+1.  It is read-only (writes will be
  86. ignored).  Reading the port yields the state of the five status input
  87. pins on the parallel port connector at the time of the read access:
  88.  
  89.         7 6 5 4 3 2 1 0
  90.         * . . . . . . .  Busy . . (pin 11), high=0, low=1 (inverted)
  91.         . * . . . . . .  Ack  . . (pin 10), high=1, low=0 (true)
  92.         . . * . . . . .  No paper (pin 12), high=1, low=0 (true)
  93.         . . . * . . . .  Selected (pin 13), high=1, low=0 (true)
  94.         . . . . * . . .  Error. . (pin 15), high=1, low=0 (true)
  95.         . . . . . * * *  Undefined
  96.  
  97. 3.3  CONTROL REGISTER
  98.  
  99. The control register is at IOBase+2.  It is read/write:
  100.  
  101.         7 6 5 4 3 2 1 0
  102.         * * . . . . . .  Unused (undefined on read, ignored on write)
  103.         . . * . . . . .  Bidirectional control, see below
  104.         . . . * . . . .  Interrupt control, 1=enable, 0=disable
  105.         . . . . * . . .  Select . . (pin 17), 1=low, 0=high (inverted)
  106.         . . . . . * . .  Initialize (pin 16), 1=high, 0=low (true)
  107.         . . . . . . * .  Auto Feed  (pin 14), 1=low, 0=high (inverted)
  108.         . . . . . . . *  Strobe . . (pin 1),  1=low, 0=high (inverted)
  109.  
  110. 3.3.1  BIDIRECTIONAL CONTROL BIT
  111.  
  112. The bidirectional control bit is only supported on true bidirectional
  113. ports - on other ports, it behaves like bits 7 and 6.  On a proper
  114. bidirectional port, setting this bit to '1' causes the outputs of the
  115. buffer that drives pins 2 through 9 of the 25-pin connector to go into
  116. a high-impedance state, so that data can be _input_ on those pins.
  117.  
  118. In this state, values written to the data register will be stored in
  119. the latch chip, but not asserted on the connector, and reading the
  120. data register will yield the states of the pins, which may be driven
  121. by an external device without stressing or damaging the port driver.
  122.  
  123. Also note that on some machines, another port must be set correctly
  124. to enable the bidirectional features, in addition to this bit.
  125. I suspect this applies to machines with the parallel port integrated
  126. on the motherboard as part of the motherboard chipset, but I do not
  127. have details, sorry.
  128.  
  129. On some parallel port cards, bidirectional mode must be enabled by a
  130. jumper setting.  With this setting enabled, the bidirectional
  131. control bit will be able to enable the bidirectional input mode.
  132.  
  133. 3.3.2  INTERRUPT ENABLE BIT
  134.  
  135. DOS and BIOS do not use the interrupt facility of the parallel port
  136. during printing.  OS/2 versions up to 2.11 did use and rely on the
  137. parallel port interrupt but OS/2 Warp does not by default.
  138.  
  139. For experimenters, the interrupt facility is useful as a general
  140. purpose externally triggerable interrupt input.
  141.  
  142. The interrupt control bit controls a tristate buffer that drives the
  143. IRQ line.  Setting the bit to '1' enables the buffer, and an IRQ will
  144. be triggered on each falling edge (high to low transition) of the Ack
  145. signal on pin 10 of the 25-pin connector.  Disabling the interrupt
  146. allows other devices to use the IRQ line.
  147.  
  148. The actual IRQ number is either hardwired (by convention, the port at
  149. 3BCh uses IRQ7), or is jumper-selectable (IRQ5 is a common choice).
  150. Sound cards, in particular, tend to use IRQ7 for their own purposes.
  151.  
  152. To use the IRQ you must also enable the interrupt via the interrupt
  153. mask register in the interrupt controller, at I/O address 21h, and
  154. your interrupt handler must send an EOI on exit.  DOS technical
  155. programming references have notes on writing interrupt handlers.
  156.  
  157. 3.3.3  PRINTER CONTROL BITS
  158.  
  159. The bottom four bits are latched and presented on the parallel port
  160. connector, much like the data register.  Three of them are inverted,
  161. so writing a '1' will output a low voltage on the port pin for them.
  162.  
  163. These four outputs are open collector outputs with pullup resistors,
  164. so an external device can force them low without stressing the driver
  165. in the PC, and they can even be used as inputs.
  166.  
  167. To use them as inputs, write 0100 binary to the bottom four bits of
  168. the control register.  This sets the outputs all high, so they are
  169. pulled high by the pullup resistors (typically 4700 ohms).  An
  170. external device can then pull them low, and you can read the pin
  171. states by reading the control register.  Remember to allow for the
  172. inversion on three of the pins.
  173.  
  174. If you are using this technique, the control register is not strictly
  175. 'read/write', because you may not read what you write (or wrote).
  176.  
  177. 4  SAMPLE PROGRAM - DETERMINE WHETHER A PORT IS BIDIRECTIONAL
  178.  
  179. This program reports for LPT1, LPT2, and LPT3 whether the port exists
  180. and whether it is bidirectional, i.e. setting the bidirectional control
  181. bit causes the port to go into high-impedance (tri-state) mode.  This
  182. program is written for Borland C.  Change outportb() and inportb() to
  183. outp() and inp() for Microsoft C, I think.  I did not have a machine
  184. with a bidirectional port with which to test this program fully, so
  185. please drop me a line if you can confirm that it does or doesn't work.
  186.  
  187. Save this code to BIDIR.C and compile with:
  188.  
  189.    bcc -I<include_path> -L<library_path> bidir.c
  190.  
  191. --------------------------- snip snip snip ---------------------------
  192. #include <dos.h>
  193. #include <process.h>
  194. #include <stdio.h>
  195.  
  196. /* The following function returns the I/O base address of the nominated
  197.    parallel port.  The input value must be 1 to 3.  If the return value
  198.    is zero, the specified port does not exist. */
  199.  
  200. unsigned int get_lptport_iobase(unsigned int lptport_num) {
  201.    return *((unsigned int far *)MK_FP(0x40, 6) + lptport_num);
  202.    }
  203.  
  204. /* Checks whether the port's data register retains data, returns 1 if
  205.    so, 0 if not.  The data register retains data on non-bidirectional
  206.    ports, but on bidirectional ports in high impedance (tri-state)
  207.    mode, the data register will not retain data. */
  208.  
  209. unsigned int test_retention(unsigned int iobase) {
  210.    outportb(iobase, 0x55);                      /* Write a new value */
  211.    (void) inportb(iobase);                      /* Delay */
  212.    if (inportb(iobase) != 0x55) {
  213.       return 0;                                 /* Did not retain data */
  214.       }
  215.    outportb(iobase, 0xAA);                      /* Write another new value */
  216.    (void) inportb(iobase);                      /* Delay */
  217.    if (inportb(iobase) != 0xAA) {
  218.       return 0;                                 /* Did not retain data */
  219.       }
  220.    return 1;                                    /* Retained data alright */
  221.    }
  222.  
  223. void report_port_type(unsigned int portnum) {
  224.    unsigned int iobase, oldctrl, oldval;
  225.    iobase = get_lptport_iobase(portnum);
  226.    if (iobase == 0) {
  227.       printf("LPT%d does not exist\n", portnum);
  228.       return;
  229.       }
  230.    oldctrl = inportb(iobase+2);
  231.    outportb(iobase+2, oldctrl & 0xDF);          /* Bidir off */
  232.    (void) inportb(iobase);                      /* Delay */
  233.    oldval = inportb(iobase);                    /* Keep old data */
  234.    if (test_retention(iobase) == 0) {
  235.       printf("LPT%d appears to be faulty!\n", portnum);
  236.       outportb(iobase+2, oldctrl);
  237.       outportb(iobase, oldval);
  238.       return;
  239.       }
  240.    outportb(iobase+2, oldctrl | 0x20);          /* Bidir on */
  241.    printf("LPT%d %s bidirectional\n", portnum,
  242.       (test_retention(iobase)) ? "is not" : "is");
  243.    outportb(iobase+2, oldctrl);                 /* Put it back */
  244.    outportb(iobase, oldval);                    /* Restore data */
  245.    return;
  246.    }
  247.  
  248. void main(void) {
  249.    unsigned int portnum;
  250.    for (portnum = 1; portnum < 4; ++portnum)
  251.       report_port_type(portnum);
  252.       exit(0);
  253.    }
  254. --------------------------- snip snip snip ---------------------------
  255.  
  256. 5.  FILE TRANSFER PROGRAM CABLES
  257.  
  258. The parallel-to-parallel cable is used by DRDOS's INTERLNK program.
  259. Apparently Laplink and FastLynx cables are the same.  The pin-to-pin
  260. connection between two male 25-pin D-sub connectors is: 2-15, 3-13,
  261. 4-12, 5-10, 6-11, and the reverse: 15-2, 13-3, 12-4, 10-5, and 11-6,
  262. and ground: 25-25.  This requires eleven wires.  If you have spare
  263. wires, link some extra grounds together.  Pins 18 to 25 inclusive are
  264. grounds.  A very long cable may be unreliable, limit it to 10 metres.
  265.  
  266. 6.  DISCLAIMER
  267.  
  268. In no event shall the author be liable for any damages whatsoever
  269. for any loss relating to this document.  Use it at your own risk!
  270.  
  271. End of the PC Parallel Port Mini-FAQ.
  272.